package com.aispeech.asr.apis.ssc.event;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationListener;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;

import com.aispeech.asr.apis.ssc.beans.AudioPrepare;
import com.aispeech.asr.apis.ssc.beans.Completer;
import com.aispeech.asr.apis.ssc.beans.Downloader;
import com.aispeech.asr.apis.ssc.beans.Paragrapher;
import com.aispeech.asr.apis.ssc.beans.SpeakerSegmentationClusteringUseInVpr;
import com.aispeech.asr.apis.ssc.beans.Vprer;
import com.aispeech.asr.apis.ssc.service.ProgressManager;
import com.aispeech.asr.comm.enums.ErrorCode;
import com.aispeech.asr.comm.exceptions.AsrException;

import lombok.extern.slf4j.Slf4j;
import reactor.core.publisher.Mono;

@Slf4j
@Component
public class SscEventListener implements ApplicationListener<SscEvent> {
    @Autowired
    ApplicationContext applicationContext;
    private final ProgressManager progressManager;

    public SscEventListener(ProgressManager progressManager) {
        this.progressManager = progressManager;
    }

    @Override
    @Async
    public void onApplicationEvent(SscEvent sscEvent) {
        log.info("[ Worker ] received task: {}, ssc: {}, current progress: {}, begin...",
                sscEvent.getTaskDoc().getId(),
                sscEvent.getTaskDoc().getProgress());

        Downloader downloader = applicationContext.getBean(Downloader.class);
        SpeakerSegmentationClusteringUseInVpr ssc = applicationContext.getBean(SpeakerSegmentationClusteringUseInVpr.class);
        AudioPrepare audioPreparer = applicationContext.getBean(AudioPrepare.class);
        Vprer vprer = applicationContext.getBean(Vprer.class);
        Paragrapher paragrapher = applicationContext.getBean(Paragrapher.class);
        Completer completer = applicationContext.getBean(Completer.class);

        Mono.just(sscEvent)               	// 1. 初始化context，整个任务流程中随时可用
                .flatMap(downloader)        // 2.根据file path下载音频
                .map(ssc) 					// 3.SCC
                .map(audioPreparer)			// 4.根据ssc的align信息准备送vpr的音频   //TODO
                .flatMap(vprer) 			// 5.拿准备好的音频去做vpr，得出谁是工作人员 //不知道是否正确
                .map(paragrapher) 			// 6.分段落  //TODO
                .flatMap(completer) 		// 7.结果
                .doOnError(throwable -> {
                    int errid = ErrorCode.ERR_UNKNOWN.errid;
                    String error = ErrorCode.ERR_UNKNOWN.error;

                    if (throwable instanceof AsrException) {
                        AsrException asrException = (AsrException) throwable;
                        errid = asrException.getCode();
                        error = asrException.getMessage();
                    }

                    log.error(
                            String.format("[ Worker ] internal error. task:%s, metrics: %s",
                                    sscEvent.getTaskDoc().getId(), sscEvent.getTaskDoc().getMetrics()),
                            throwable);
                    progressManager.failed(sscEvent, errid, error);
                })
                .subscribe(
//                        event -> log.info("[ Worker ] done task: {}", event.getTaskDoc().getId())
                );
    }
}
